﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZoneFiveSoftware.Common.Visuals;
using System.Net;
using System.IO;
using System.Web;
using System.Xml;
using System.Windows.Forms;
using System.Data;
using ZoneFiveSoftware.Common.Visuals.Fitness;
using ZoneFiveSoftware.Common.Data.Fitness;
using System.Globalization;

namespace HackersDiet
{
    class HDSettingsAction : IAction
    {
        #region IAction Members

        public bool Enabled
        {
            get { return false; }
        }

        public bool HasMenuArrow
        {
            get { return false; }
        }

        public System.Drawing.Image Image
        {
            get { return null; }
        }

        public void Refresh()
        {
            // do nothing
        }

        public void Run(System.Drawing.Rectangle rectButton)
        {
            // do nothing;
            PropertyChanged.GetType();
        }

        public string Title
        {
            get { return "Settings"; }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    class HDWebsiteImportAction : IAction
    {
        public static DataGrid DG = new DataGrid();

        #region IAction Members

        public bool Enabled
        {
            get { return true; }
        }

        public bool HasMenuArrow
        {
            get { return false; }
        }

        public System.Drawing.Image Image
        {
            get { return null; }
        }

        public void Refresh()
        {
            return;
        }

        public void Run(System.Drawing.Rectangle rectButton)
        {
            SettingsPageForm settings = new SettingsPageForm();
            
            if (settings.ShowDialog() != DialogResult.OK)
                return;

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://www.physicsdiet.com/FitnessLog.aspx");

            CookieContainer cookies = new CookieContainer();
            webRequest.CookieContainer = cookies;

            //Get the response handle, we have no true response yet!
            HttpWebResponse WebResp = (HttpWebResponse)webRequest.GetResponse();
            //Now, we read the response (the string), and output it.
            Stream Answer = WebResp.GetResponseStream();
            StreamReader _Answer = new StreamReader(Answer);
            string responseData = _Answer.ReadToEnd();

            // extract the viewstate value and build out POST data
            string USERNAME = HttpUtility.UrlEncodeUnicode(settings.PhysicsDietSettings.Username);
            string PASSWORD = HttpUtility.UrlEncodeUnicode(settings.PhysicsDietSettings.Password);
            string BUTTONID = HttpUtility.UrlEncodeUnicode("Log In");
            string viewState = ExtractStateValue(responseData, "__VIEWSTATE");
            //string eventTarget = ExtractStateValue(responseData, "__EVENTTARGET");
            //string eventArgument = ExtractStateValue(responseData, "__EVENTARGUMENT");
            string eventValidation = ExtractStateValue(responseData, "__EVENTVALIDATION");

            StringBuilder postDataFormat = new StringBuilder();
            postDataFormat.AppendFormat("__VIEWSTATE={0}&", viewState);
            postDataFormat.AppendFormat("ctl00$ctl00$MainContentPlaceholder$MainContentPlaceholder$LoginView1$Login1$UserName={0}&", USERNAME);
            postDataFormat.AppendFormat("ctl00$ctl00$MainContentPlaceholder$MainContentPlaceholder$LoginView1$Login1$Password={0}&", PASSWORD);
            postDataFormat.AppendFormat("ctl00$ctl00$MainContentPlaceholder$MainContentPlaceholder$LoginView1$Login1$RememberMe={0}&", "off");
            postDataFormat.AppendFormat("ctl00$ctl00$MainContentPlaceholder$MainContentPlaceholder$LoginView1$Login1$LoginButton={0}&", BUTTONID);
            postDataFormat.AppendFormat("__EVENTVALIDATION={0}", eventValidation);

            string postData = postDataFormat.ToString();

            HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create("http://www.physicsdiet.com/FitnessLog.aspx");
            webRequest1.Method = "POST";
            webRequest1.ContentType = "application/x-www-form-urlencoded";
            webRequest1.ContentLength = postData.Length;
            webRequest1.CookieContainer = cookies;

            // write the form values into the request message
            StreamWriter requestWriter = new StreamWriter(webRequest1.GetRequestStream());
            requestWriter.Write(postData);
            requestWriter.Close();

            // we don't need the contents of the response, just the cookie it issues
            WebResp = (HttpWebResponse)webRequest1.GetResponse();

            for (int i = 1; i <= settings.PhysicsDietSettings.NumberOfPagesToImport; i++)
            {
                HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(string.Format("http://www.physicsdiet.com/FitnessLog.aspx?p={0}",i));
                wr.CookieContainer = cookies;
                WebResp = (HttpWebResponse)wr.GetResponse();

                Answer = WebResp.GetResponseStream();
                _Answer = new StreamReader(Answer);
                responseData = _Answer.ReadToEnd();

                ParseDataGrid(responseData);
            }
          
            return;
        }

        void ParseDataGrid(string html)
        {
            IApplication application = Plugin.GetApplication();

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(html);

            XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
            manager.AddNamespace("x", "http://www.w3.org/1999/xhtml");

            XmlNodeList node = doc.SelectNodes("//x:table[@id='ctl00_ctl00_MainContentPlaceholder_MainContentPlaceholder_LoginView1_GridView1']/x:tr/x:th", manager);
            XmlNodeList node1 = doc.SelectNodes("//x:table[@id='ctl00_ctl00_MainContentPlaceholder_MainContentPlaceholder_LoginView1_GridView1']/x:tr/x:td", manager);

            if (node != null && node1 != null)
            {
                // TODO: Allow user to specify which columns to import
                string[] columnsWantedHeaders = new string[] { "Date", "Weight", "Body Fat %", "Heart Rate", "Calories Eaten" };
                int[] columnsWantedIndex = new int[columnsWantedHeaders.Length];

                for (int j = 0; j < node.Count; j++)
                {
                    string header = node[j].InnerText.Replace("\r", string.Empty).Replace("\n", string.Empty).Trim();

                    for (int i = 0; i < columnsWantedHeaders.Length; i++)
                    {
                        if (header == columnsWantedHeaders[i])
                        {
                            columnsWantedIndex[i] = j;
                            continue;
                        }
                    }
                }

                for (int j = 0; j < node1.Count - 1; j += node.Count)
                {
                    for (int k = 0; k < node.Count; k++)
                    {
                        DateTime date = DateTime.Parse(node1[j + columnsWantedIndex[0]].InnerText, new CultureInfo("en-US"));

                        IAthleteInfoEntry entry = application.Logbook.Athlete.InfoEntries.EntryForDate(date);
                        entry.WeightKilograms = float.Parse(node1[j + columnsWantedIndex[1]].InnerText);
                        entry.BodyFatPercentage = float.Parse(node1[j + columnsWantedIndex[2]].InnerText);
                        entry.RestingHeartRatePerMinute = float.Parse(node1[j + columnsWantedIndex[3]].InnerText);
                        entry.CaloriesConsumed = float.Parse(node1[j + columnsWantedIndex[4]].InnerText);
                    }    
                }

                //XmlNodeList tableRows = node.SelectNodes("//x:tr", manager);
                
                //// first row will be headers
                //XmlNode headerRow = node.FirstChild;

                //XmlNodeList headerNodes = headerRow.SelectNodes("//x:th", manager);

                //string[] headers = new string[headerNodes.Count];

                //for (int i = 0; i < headerNodes.Count; i++)
                //{
                //    headers[i] = headerNodes[i].InnerText.Replace("\r",string.Empty).Replace("\n",string.Empty);
                //}

                ////XmlNodeList rows = tableRows.SelectNodes("//x:tr", manager);
                //Dictionary<DateTime, float> weightDict = new Dictionary<DateTime, float>();
                //foreach (XmlNode row in tableRows)
                //{
                //    XmlNodeList entries = row.SelectNodes("//x:td", manager);

                  
                //    foreach (XmlNode entry in entries)
                //    {
                //        string s = entry.InnerText.Replace("\r", string.Empty).Replace("\n", string.Empty);
                //        Console.Write(s);
                //    }
                //}
            }
        }

        public string Title
        {
            get { return "Import from PhysicsDiet"; }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        #endregion

        private string ExtractStateValue(string s, string stateName)
        {
            string valueDelimiter = "value=\"";

            int viewStateNamePosition = s.IndexOf(stateName);
            int viewStateValuePosition = s.IndexOf(
                  valueDelimiter, viewStateNamePosition
               );

            int viewStateStartPosition = viewStateValuePosition +
                                         valueDelimiter.Length;
            int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

            return HttpUtility.UrlEncodeUnicode(s.Substring(
                        viewStateStartPosition,
                        viewStateEndPosition - viewStateStartPosition
                     ));
        }
    }
}
